﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProjectEulerSolutions
{
    class Problem55 : IProblem
    {
        public string Calculate()
        {

            int count = 0; //nula
            int limitIterations = 50;
            int limit = 10000;

            for (int i = 1; i < limit; i++)
            {
                if (i == 191)
                {

                }

                byte[] number = FromNumber(i);
                bool found = false;
                for (int j = 0; j < limitIterations; j++)
                {
                    number = AddInverse(number);
                    if (IsPalindrome(number))
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                    count++;
            }
            



            return count.ToString();
        }

        static int DigitLimit = 100;


        byte[] FromNumber(int n)
        {
            byte[] number = new byte[DigitLimit];

            int pointer = number.Length - 1;

            while (n != 0)
            {
                number[pointer] = (byte)(n % 10);
                n /= 10;
                pointer--;
            }

            return number;
        }

        bool IsPalindrome(byte[] source)
        {
            int leftPointer = 0;
            int rightPointer = source.Length - 1;

            while (leftPointer < source.Length && source[leftPointer] == 0)
                leftPointer++;

            while (leftPointer <= rightPointer)
            {
                if (source[leftPointer] != source[rightPointer])
                    return false;

                leftPointer++;
                rightPointer--;
            }
            return true;
        }

        byte[] AddInverse(byte[] source)
        {
            byte[] result = new byte[source.Length];

            int sourcePointer = 0;
            int inversePointer = source.Length - 1;

            while (sourcePointer < source.Length && source[sourcePointer] == 0)
                sourcePointer++;

            while (sourcePointer < source.Length)
            {
                int tempResult = source[sourcePointer] + source[inversePointer];

                int overflow = tempResult / 10;
                int overflowPointer = 1;
                result[sourcePointer] = (byte)(tempResult % 10);

                while (overflow != 0)
                {
                    result[sourcePointer - overflowPointer]++;
                    overflow = result[sourcePointer - overflowPointer] / 10;
                    result[sourcePointer - overflowPointer] %= 10;
                    overflowPointer++;
                }

                sourcePointer++;
                inversePointer--;
            }

            return result;
        }
    }
}
